package org.jground.rx.ui.zk;

import java.util.HashMap;
import java.util.Stack;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jground.rx.IRXObject;
import org.jground.rx.RXObjectService;
import org.jground.rx.RXSystem;
import org.jground.rx.ui.IMainFrame;
import org.jground.rx.ui.IMainPanel;
import org.jground.rx.ui.pref.PrefService;
import org.jground.rx.ui.zk.report.UIReportWindow;
import org.jground.util.ArrayUtils;
import org.jground.zk.util.ZKUtils;
import org.jground.zk.zulX.HboxX;
import org.jground.zk.zulX.WindowX;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.api.HtmlBasedComponent;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Div;
import org.zkoss.zul.Label;

public class UIFrame extends WindowX implements IMainFrame<Component> {

    private static Log logger = LogFactory.getLog(UIFrame.class);
    //
    //
    //
    private UIMasterFrame uiMaster;
    //
    private HashMap<String, UIEditWindow> editWindows = new HashMap<String, UIEditWindow>();
    private HashMap<String, UIViewWindow> viewWindows = new HashMap<String, UIViewWindow>();
    private HashMap<String, UIViewSynopsis> synopsisPanels = new HashMap<String, UIViewSynopsis>();
    private UISynopsisRendererFactory uiSynopsisRendererFactory;
    private HashMap<String, UIReportWindow> reportWindows;
    private UIDataObjectRefSearchPanel refSearchPanel;
    //
    private UINavigationPanel navigationPanel;
    private IMainPanel<Component> homePanel;
    private UISearchWindow searchPanel;
    //
    private HtmlBasedComponent centerContainer;
    private HboxX footer;
    //
    private Stack<IMainPanel<Component>> stackedDialogs = new Stack<IMainPanel<Component>>();

    public UIFrame(UIMasterFrame uiMaster) {
        logger.debug("init");
        //
        this.uiMaster = uiMaster;
        uiSynopsisRendererFactory = new UISynopsisRendererFactory(this);
        //
        // COMPONENTS
        //
        // setStyle("padding:40px");
        // setStyle("border:red dashed 4px");
        setBorder("normal");
        //
        navigationPanel = new UINavigationPanel(this);
        //centerContainer = new Panelchildren();
        searchPanel = new UISearchWindow(this);
        //
        String[] roles = RXSystem.getRXPrincipalMethods().getUserRoles();
        Label footerLabel = new Label(RXSystem.getRXPrincipalMethods().getUserName() + " / " + ArrayUtils.join(roles)
                + " / " + RXSystem.getRXPrincipalMethods().getLang());
        footerLabel.setSclass(UIStyles.BAR);
        footer = new HboxX(footerLabel);
        footer.setStyle("border: dotted 1px gray; margin-top: 10px; font-size:0.8em");
        footer.setWidth("100%");
        //
        // LAYOUT
        //
        add(navigationPanel);
        //
        // Columnlayout columnLayout = new Columnlayout();
        // add(columnLayout);
        // Columnchildren columnChild = new Columnchildren();
        // columnChild.setWidth("98%");
        // columnChild.setParent(columnLayout);
        // //
        // Panel pan = new Panel();
        // pan.setParent(columnChild);
        // centerContainer.setParent(pan);

        Borderlayout borderLayout = new Borderlayout();
        add(borderLayout);

        // DIAG centerContainer
        centerContainer = new Div();
        //((Center) centerContainer).setFlex(true);
        centerContainer.setStyle("border:0px dotted green");
//        centerContainer.setParent(borderLayout);
        add(centerContainer);
        //
        add(footer);

        homePanel = searchPanel;
        showHomePanel();
        //
        // EVENTS
        //
    }

    public IMainPanel<Component> getCurrentMainPanel() {
        return stackedDialogs.peek();
    }

    public void setMainPanel(Long oid, boolean onStack) {
        MainPanelDelegate panel = new MainPanelDelegate(oid);
        setMainPanel(panel, onStack);
    }

    public void setMainPanel(IMainPanel<Component> panel, boolean onStack) {
        if (panel == null && (stackedDialogs.size() > 0 && panel == stackedDialogs.peek())) {
            logger.debug("Nothing to add, current panel is alredy set to the same.");
            return;
        }
        if (!onStack) {
            stackedDialogs.clear();
        }
        stackedDialogs.push(panel);
        ZKUtils.removeAllChildren(centerContainer);
        panel.beforeShow();
        panel.getView().setParent(centerContainer);
    }

    public void setMainPanel(IMainPanel<Component> panel) {
        this.setMainPanel(panel, false);
    }

    public void setHomePanel(IMainPanel<Component> panel) {
        this.homePanel = panel;
    }

    public void showHomePanel() {
        setMainPanel(getHomePanel(), false);
    }

    public IMainPanel<Component> getHomePanel() {
        return homePanel;// == null ? homePanel = new DivX(new
        // Label("NO HOME PANEL SET")) : homePanel;
    }

    public void openView(Long oid, boolean onStack) {
        getPrefService().addViewed(oid);
        // IRXObject mod = IRXObject.getById(oid);
        // UIViewWindow view = getViewWindow(mod.getMoid());
        // view.setData(mod);
        setMainPanel(oid, onStack);
    }

    public void close(Long oid) {
        MainPanelDelegate panel = new MainPanelDelegate(oid);
        closeMainPanel(panel);
    }

    public void closeMainPanel(IMainPanel<Component> panel) {
        if (stackedDialogs.size() > 0 && stackedDialogs.peek().equals(panel)) {
            panel.beforeClose();
            stackedDialogs.pop();
        }
        if (stackedDialogs.size() == 0) {
            showHomePanel();
        } else {
            setMainPanel(stackedDialogs.pop(), true);
        }
    }

    public UIEditWindow getEditWindow(String moid) {
        UIEditWindow editWindow = editWindows.get(moid);
        if (editWindow == null) {
            editWindow = createEditWindow(moid);
            editWindows.put(moid, editWindow);
        }
        return editWindow;
    }

    public UIViewWindow getViewWindow(String moid) {
        UIViewWindow viewWindow = viewWindows.get(moid);
        if (viewWindow == null) {
            viewWindow = createViewWindow(moid);
            viewWindows.put(moid, viewWindow);
        }
        return viewWindow;
    }

    public UIViewSynopsis getSynopsisViews(String moid) {
        UIViewSynopsis views = synopsisPanels.get(moid);
        if (views == null) {
            views = createSynopsisViews(moid);
            synopsisPanels.put(moid, views);
        }
        return views;
    }

    public UIReportWindow getReportWindow(String mrid) {
        if (reportWindows == null) {
            reportWindows = new HashMap<String, UIReportWindow>();
        }
        UIReportWindow reportWindow = reportWindows.get(mrid);
        if (reportWindow == null) {
            reportWindow = new UIReportWindow(this, mrid);
            reportWindows.put(mrid, reportWindow);
        }
        return reportWindow;
    }

    public UIEditWindow createEditWindow(String moid) {
        return new UIEditWindow(this, moid);
    }

    public UIViewWindow createViewWindow(String moid) {
        return new UIViewWindow(this, moid);
    }

    public UIViewSynopsis createSynopsisViews(String moid) {
        return new UIViewSynopsis(this, moid);
    }

    public UIDataObjectRefSearchPanel getRefSearchPanel() {
        return refSearchPanel == null ? refSearchPanel = new UIDataObjectRefSearchPanel(this) : refSearchPanel;
    }

    public PrefService getPrefService() {
        return uiMaster.getPrefService();
    }

    private class MainPanelDelegate implements IMainPanel<Component> {
        private Long oid;
        private UIViewWindow view;

        public MainPanelDelegate(Long oid) {
            this.oid = oid;
        }

        public void beforeClose() {
            // TODO Auto-generated method stub

        }

        public void beforeShow() {
            IRXObject mod = RXObjectService.getInstance().getById(oid);
            view = getViewWindow(mod.getMoid());
            view.setData(mod);
        }

        public Component getView() {
            return view;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof MainPanelDelegate) {
                MainPanelDelegate mpd = (MainPanelDelegate) obj;
                return mpd.oid.equals(this.oid);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return oid.hashCode();
        }

    }

    public UISynopsisRendererFactory getUISynopsisRendererFactory() {
        return uiSynopsisRendererFactory;
    }

    public void closeTopMainPanel() {
        // TODO Auto-generated method stub

    }
}